package utils

import (
	"bytes"
	"container/list"
	"encoding/binary"
	"fmt"
	"math"
	"strconv"
	"unsafe"
)

func ByteLit2Int32(data []byte) int32 {
	binBuf := bytes.NewBuffer(data)
	var x int32
	binary.Read(binBuf, binary.LittleEndian, &x)
	return x
}

func Byte2BigInt32(data []byte) int32 {
	binBuf := bytes.NewBuffer(data)
	var x int32
	binary.Read(binBuf, binary.BigEndian, &x)
	return x
}

func Byte2Int(data []byte) int {
	var ret = 0
	var len = len(data)
	var i uint = 0
	for i = 0; i < uint(len); i++ {
		ret = ret | (int(data[i]) << (i * 8))
	}
	return ret
}

func Int2Byte(data int) (ret []byte) {
	var len uintptr = unsafe.Sizeof(data)
	ret = make([]byte, len)
	var tmp int = 0xff
	var index uint = 0
	for index = 0; index < uint(len); index++ {
		ret[index] = byte((tmp << (index * 8) & data) >> (index * 8))
	}
	return ret
}

func Reverse(s string) string {
	r := []rune(s)
	for i, j := 0, len(r)-1; i < j; i, j = i+1, j-1 {
		r[i], r[j] = r[j], r[i]
	}
	return string(r)
}

func DeciNeedBytes(len int) int {
	var l int
	for {
		if len <= 0 {
			break
		}

		// 7-9
		if len >= 9 {
			l += 4
			len -= 9
		}
		if len == 8 {
			l += 4
			len -= 9
		}
		if len == 7 {
			l += 4
			len -= 7
		}
		// 5-6
		if len == 6 {
			l += 3
			len -= 6
		}
		if len == 5 {
			l += 3
			len -= 5
		}
		// 3-4
		if len == 4 {
			l += 2
			len -= 4
		}
		if len == 3 {
			l += 2
			len -= 3
		}
		// 1-2
		if len == 2 {
			l += 1
			len -= 2
		}
		if len == 1 {
			l += 1
			len -= 1
		}
	}
	return l
}

func CalcIntToDate(i int) string {

	dd := i % 32
	mm := ((i - (i % 32)) / 32) % 16
	yy := (i - (mm * 32) - dd) / (16 * 32)

	fmt.Println(dd)
	fmt.Println(mm)
	fmt.Println(yy)

	var x string

	if yy < 1000 && yy > 100 {
		x += "0" + strconv.Itoa(yy)
	} else if yy < 100 && yy > 10 {
		x += "00" + strconv.Itoa(yy)
	} else if yy < 10 {
		x += "000" + strconv.Itoa(yy)
	}
	if dd < 10 {
		x += "0" + strconv.Itoa(dd)
	} else {
		x += strconv.Itoa(dd)
	}
	if mm < 10 {
		x += "0" + strconv.Itoa(mm)
	} else {
		x += strconv.Itoa(mm)
	}

	return x
}

func CalcStringToTime(input string) string {
	stack := list.New()

	var sum int
	var stnum, conum float64 = 0, 2

	for _, c := range input {
		// 入栈 type rune
		stack.PushBack(c)
	}

	// 出栈
	for e := stack.Back(); e != nil; e = e.Prev() {
		// rune是int32的别名
		v := e.Value.(int32)
		sum += int(v-48) * int(math.Pow(conum, stnum))
		stnum++
	}
	var x string
	if sum < 10 {
		x += "0" + strconv.Itoa(sum)
	} else {
		x += strconv.Itoa(sum)
	}
	return x
}
